---
title: Getting Started
description: "Request access and run your first analytics query"
---

## Request Access

<Warning>
  **Analytics is currently in private beta and available by request only.**
</Warning>

To get started:

1. **Find your workspace ID** in the Unkey dashboard settings
2. **Email us** at [support@unkey.dev](mailto:support@unkey.dev) with:
   - Your workspace ID
   - Your use case (billing, dashboards, reporting, etc.)
   - Expected query volume

We'll enable analytics for your workspace and send you confirmation.

## Authentication

Analytics queries require a root key with analytics permissions. Create one in your dashboard:

1. Go to **Settings** → **Root Keys**
2. Click **Create New Root Key**
3. Select permissions: `api.*.read_analytics` OR `api.<api_id>.read_analytics`
4. Copy and securely store your root key

<Warning>
  Root keys have powerful permissions. Store them securely and never commit them
  to version control.
</Warning>

## Your First Query

Once you have access, execute your first analytics query using the `/v2/analytics.getVerifications` endpoint.

### Count Total Verifications

Count the total number of key verifications in the last 7 days across all your APIs to get a high-level view of your overall usage volume.

<CodeGroup>
```sql SQL
SELECT SUM(count) as total
FROM key_verifications_per_day_v1
WHERE time >= now() - INTERVAL 7 DAY
```

```bash cURL
curl -X POST https://api.unkey.com/v2/analytics.getVerifications \
  -H "Authorization: Bearer <YOUR_ROOT_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "SELECT SUM(count) as total FROM key_verifications_per_day_v1 WHERE time >= now() - INTERVAL 7 DAY"
  }'
```

</CodeGroup>

### Break Down by Outcome

Group verifications by their outcome (`VALID`, `RATE_LIMITED`, `USAGE_EXCEEDED`, etc.) over the last 24 hours to understand the distribution of successful vs. failed requests.

<CodeGroup>
```sql SQL
SELECT
  outcome,
  SUM(count) as count
FROM key_verifications_per_hour_v1
WHERE time >= now() - INTERVAL 24 HOUR
GROUP BY outcome
ORDER BY count DESC
```

```bash cURL
curl -X POST https://api.unkey.com/v2/analytics.getVerifications \
  -H "Authorization: Bearer <YOUR_ROOT_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "SELECT outcome, SUM(count) as count FROM key_verifications_per_hour_v1 WHERE time >= now() - INTERVAL 24 HOUR GROUP BY outcome ORDER BY count DESC"
  }'
```

</CodeGroup>

### Top Users by Usage

Identify your most active users by counting their total verifications over the last 30 days to spot power users or potential abuse patterns.

<CodeGroup>
```sql SQL
SELECT
  external_id,
  SUM(count) as verifications
FROM key_verifications_per_day_v1
WHERE time >= now() - INTERVAL 30 DAY
GROUP BY external_id
ORDER BY verifications DESC
LIMIT 10
```

```bash cURL
curl -X POST https://api.unkey.com/v2/analytics.getVerifications \
  -H "Authorization: Bearer <YOUR_ROOT_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "SELECT external_id, SUM(count) as verifications FROM key_verifications_per_day_v1 WHERE time >= now() - INTERVAL 30 DAY GROUP BY external_id ORDER BY verifications DESC LIMIT 10"
  }'
```

</CodeGroup>

<Tip>
  **Performance tip:** For longer time ranges, use pre-aggregated tables instead of the raw table:
  - `key_verifications_per_minute_v1` - For queries spanning hours
  - `key_verifications_per_hour_v1` - For queries spanning days
  - `key_verifications_per_day_v1` - For queries spanning weeks/months
  - `key_verifications_per_month_v1` - For queries spanning years

Use `SUM(count)` instead of `COUNT(*)` with aggregated tables. They scan far fewer rows and are much faster.

</Tip>

<Tip>
  Check out the [Query Examples](/analytics/query-examples) page for 30+
  ready-to-use queries covering billing, monitoring, and analytics use cases.
</Tip>

## Understanding the Response

Analytics queries return data as an array of objects:

```json
{
  "meta": {
    "requestId": "req_xxx"
  },
  "data": [
    { "outcome": "VALID", "count": 1234 },
    { "outcome": "RATE_LIMITED", "count": 56 },
    { "outcome": "USAGE_EXCEEDED", "count": 12 }
  ]
}
```

Each object in the `data` array contains fields from your SELECT clause. The field names match the column names or aliases you specified in your query.

## Filtering by API or User

You can filter queries to specific APIs or users. Use `key_space_id` to filter by API (find this identifier in your API settings) and `external_id` to filter by user. These fields support standard SQL operators: `=`, `!=`, `IN`, `NOT IN`, `<`, `>`, etc.

<Note>
  **Automatic filtering:** All queries are automatically filtered based on your root key's permissions:

  - **Workspace filtering:** All queries are scoped to your workspace. You **do not need** to filter by `workspace_id`.
  - **API filtering:** If your root key has `api.<api_id>.read_analytics` permissions (scoped to a specific API), queries are automatically filtered to that API's `key_space_id`. If your root key has `api.*.read_analytics` (all APIs), you should filter by `key_space_id` yourself to query specific APIs.
</Note>

<Note>
  Queries are subject to resource limits (execution time, memory, result size,
  and quota). See [Query Restrictions](/analytics/query-restrictions) for
  complete details on limits and error codes.
</Note>
